#!/usr/bin/env python

from irc.client import NickMask, is_channel

from kivy.logger import Logger

from amgineirc.viewModel.channels.channelViewModel import ChannelViewModel
from amgineirc.viewModel.channels.prvmsgViewModel import PrvmsgViewModel
from amgineirc.viewModel.channels.serverViewModel import ServerViewModel
from amgineirc.viewModel.viewModel import ViewModel
from amgineirc.view.channels.defaultView import DefaultView

class ConnectionsViewModel(ViewModel):
    """a view model for the connections notebook view.
    should be able to add and remove channels views
    """

    updated_suffix = ' *'
    default_suffix = '  '
    
    def __init__(self, view, appdata):
        ViewModel.__init__(self, view)
        self._appdata = appdata
        appdata['connection_vm'] = self
        appdata['client'].register_on_connect(self.handle_on_connect)
        appdata['client'].register_on_disconnect(self.handle_on_disconnect)
        

    # methods for adding and removing pages
    
    def handle_on_connect(self):
        # self.view.default_tab_text = "Disconnect"
        pass
        
    def handle_on_disconnect(self):
        # self.view.default_tab_text = "Connect"
        pass
        
    def add_server_connection(self, target):
        # raise connections page ( which is self.view )
        self._appdata['app_view'].upper_view.raise_connections_page()
        # if there is not server page then create one
        th = self._get_connection_page(target, target)
        if th is None:
            # add the page
            name = target + ConnectionsViewModel.default_suffix
            th = self.view.add_server_connection(name, target)
        # raise the page
        self.view.switch_to(th)
        # connect to the server
        th.content.view_model.connect()

    def resend_client_event(self, server, evtarg, evtype, evsource, evargs):
        tabs = self._get_tab_list()
        for th in tabs:
            vm = th.content.view_model
            if vm.server == server and vm.target == evtarg:
                vm.handle_client_event(evtarg, evtype, server, evsource, evargs)

    def update_user_lists(self, nick, server, is_trusted):
        tabs = self._get_tab_list()
        for th in tabs:
            vm = th.content.view_model
            if isinstance(vm, ServerViewModel):
                if vm.server == server:
                    vm.set_nick_trusted(nick, is_trusted)

    def update_user_lists_quit(self, nick, server):
        # called by the server vm
        tabs = self._get_tab_list()
        for th in tabs:
            vm = th.content.view_model
            if isinstance(vm, ChannelViewModel):
                if vm.server == server:
                    vm.user_part(nick)

    def update_nick_change(self, server, old_nick, new_nick):
        # called by the server vm
        tabs = self._get_tab_list()
        for th in tabs:
            vm = th.content.view_model
            if isinstance(vm, ChannelViewModel):
                if vm.server == server:
                    vm.nick_change(old_nick, new_nick)
            elif isinstance(vm, PrvmsgViewModel):
                if vm.server == server:
                    if vm.nick_change(old_nick, new_nick):
                        # change the tab text
                        th.text = new_nick
                        self.page_updated_th(th)

    def have_connection_page(self, server, target):
        th = self._get_connection_page(server, target)
        return th is not None

    def _get_tab_list(self):
        tl = []
        for th in self.view.tab_list:
            if not isinstance(th.content, DefaultView):
                tl.append(th)
        return tl

    def _get_connection_page(self, server, target):
        tabs = self._get_tab_list()
        if server == target:
            # server connection
            # the vm may or may not have a connection
            for th in tabs:
                vm = th.content.view_model
                if (vm.server == server or vm.server is None) and vm.target == server:
                    return th
        else:
            # not a server connection
            for th in tabs:
                vm = th.content.view_model
                if vm.server == server and vm.target == target:
                    return th
        return None
    
    def remove_connection_page(self, server, target):
        th = self._get_connection_page(server, target)
        if th is not None:
            vm = th.content.view_model
            self.view.remove_widget(th)
            vm.handle_on_remove()

    def add_channel_connection(self, connection, target):
        if connection is not None:
            # join the target
            # raise connections page ( which is this view model's view )
            self._appdata['app_view'].upper_view.raise_connections_page()
            th = self._get_connection_page(connection.server, target)
            if th is None:
                # add the page
                name = target + ConnectionsViewModel.default_suffix
                th = self.view.add_channel_connection(name, connection, target)
            # raise the page
            self.view.switch_to(th)
            vm = th.content.view_model
            vm.handle_on_connect(connection)
            
    def add_privmsg_connection(self, connection, target, send_message='', received_message=''):
        if connection is not None:
            # find the trusted user record or None if not a trusted user
            record = self._appdata['trusted_users'].get_user(target, connection.server)
            if record is not None \
            and not self._appdata['trusted_users'].have_configuration_folder():
                # missing settings folder
                warning = self._appdata['trusted_users'].missing_configuration_folder_message
                self.view.message_warn(warning)
            else:
                # raise connections page ( which is this view model's view )
                self._appdata['app_view'].upper_view.raise_connections_page()
                th = self._get_connection_page(connection.server, target)
                if th is None:
                    # add the page
                    # name of window is target
                    # title is nick
                    nmask = NickMask(target)
                    name = nmask.nick + ConnectionsViewModel.default_suffix
                    th = self.view.add_prvmsg_connection(name, connection, target, record)
                # raise the page
                self.view.switch_to(th)
                # have the page send or receive the message
                if len(send_message) > 0:
                    th.content.view_model.send_opening_privmsg(send_message)
                elif len(received_message) > 0:
                    th.content.view_model.receive_opening_privmsg(received_message)
            
    def add_dcc_connection(self, dcc_connection, nick, server):
        # called by DCCHandShakeModel
        # find the trusted user record
        record = self._appdata['trusted_users'].get_user(nick, server)
        # raise connections page ( which is this view model's view )
        self._appdata['app_view'].upper_view.raise_connections_page()
        name = nick + ConnectionsViewModel.default_suffix
        # add the page
        th = self.view.add_dcc_connection(name, dcc_connection, nick, record)
        # raise the page
        self.view.switch_to(th)

    # indicate page has been updated' methods

    def page_updated(self, server, target):
        th = self._get_connection_page(server, target)
        if th is not None:
            self.page_updated_th(th)

    def page_updated_th(self, th):
        # if not the current page then show updated
        # if th is not None and th is not th.tabbed_panel.current_tab:
        if th != self.view.current_tab:
            if not th.text.endswith(ConnectionsViewModel.updated_suffix):
                # change the tab to show updated page content
                if th.text.endswith(ConnectionsViewModel.default_suffix):
                    at = 0 - len(ConnectionsViewModel.default_suffix)
                    th.text = th.text[:at] + ConnectionsViewModel.updated_suffix
                else:
                    th.text = th.text + ConnectionsViewModel.updated_suffix

    def page_unupdated(self, th):
        # change the tab to show not updated page content
        if not th.text.endswith(ConnectionsViewModel.default_suffix):
            if th.text.endswith(ConnectionsViewModel.updated_suffix):
                at = 0 - len(ConnectionsViewModel.updated_suffix)
                th.text = th.text[:at] + ConnectionsViewModel.default_suffix
            else:
                th.text = th.text + ConnectionsViewModel.default_suffix

    # internal methods
